import java.util.ArrayList;

public class PertNetwerk extends Graph {
	private ArrayList<Vertex> sorted;

	public PertNetwerk() {
		super();
		sorted = new ArrayList<Vertex>();
	}

	public void topologischSort() {
		ArrayList<Vertex> temp = (ArrayList<Vertex>) vertices.clone();
		sorted = new ArrayList<Vertex>();
		Vertex start = getVertexWithNoEdges();
		while (!vertices.isEmpty()) {
			start = getVertexWithNoEdges();
			if (start != null) {
				sorted.add(start);
				markVertex(start.getName());
			}
		}
		vertices = temp;
	}

	private void markVertex(String vertexName) {
		Vertex vertex = getVertex(vertexName);

		for (Vertex v : vertices) {
			for (Edge e : v.getInComingEdges()) {
				if (e.getStartVertex().equals(vertex)) {
					e.setMarked(true);
				}
			}
		}
		vertices.remove(vertex);
	}

	public void decideEarliestTime() {
		for (Vertex v : sorted) {
			if (v.getInComingEdges().isEmpty()) {
				v.setEarliestTime(0);
			} else {
				Vertex temp = v.getFirstTimePredecessors();
				v.setEarliestTime(temp.getEarliestTime()
						+ v.getEdge(temp).getEdgeValue());
			}
		}
	}

	public void decideLatestTime() {
		Vertex v = null;
		for (int i = sorted.size() - 1; i >= 0; i--) {
			v = sorted.get(i);
			if (!v.getOutGoingEdges().isEmpty()) {
				int latest = v.getOutGoingEdges().get(0).getEnd().getLastTime()
						- v.getOutGoingEdges().get(0).getEdgeValue();
				for (Edge e : v.getOutGoingEdges()) {
					if (latest > (e.getEnd().getLastTime() - e.getEdgeValue())) {
						latest = e.getEnd().getLastTime() - e.getEdgeValue();
					}
				}
				v.setLastTime(latest);

			} else {
				v.setLastTime(v.getEarliestTime());
			}
		}
	}

	private Vertex getVertexWithNoEdges() {
		Vertex vertex = null;
		boolean hasEdge = false;
		for (Vertex v : vertices) {
			hasEdge = false;
			for (Edge e : v.getInComingEdges()) {
				if (!e.isMarked()) {
					hasEdge = true;
				}
			}
			if (!hasEdge) {
				vertex = v;
				break;
			}
		}

		return vertex;
	}

	public String toString() {
		String receiving = "";
		for (Vertex v : sorted) {
			receiving += v.toString() + " - ";
		}
		return receiving;
	}
}
